package com.blog.common;

import com.blog.util.DateUtils;
import com.blog.util.MachineUtil;
import com.blog.util.MathDelUtil;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLDecoder;
import java.util.Iterator;


/**
 * @description:图片上传
 */
@Controller
@Slf4j
@RequestMapping("/imgUpload")
public class ImgUploadController {

    /**上传文件类型*/
    //图片
    public final static int FILE_TYPE_IMG = 1;


    /**
     * 富文本模块的上传图片
     * @param file
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping("imUploadLayedit")
    public void imUploadLayedit(@RequestParam(value="file",required=false) MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException {
        JSONObject object = uploadImg(file,request,response);
        JSONObject result = new JSONObject();
        JSONObject img = new JSONObject();
        img.put("src",JSONObject.fromObject(object.get("data")).get("urlLoad"));
        img.put("title","");
        result.put("code",0);
        result.put("msg","上传成功");
        result.put("data",img);

        MachineUtil.print(response,result.toString());
    }

    /**
     * 上传图片
     * @param file
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping("imgload")
    public void imUpload(@RequestParam(value="file",required=false) MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.printf("进入上传图片方法---------->");
        JSONObject object = uploadImg(file,request,response);
        MachineUtil.print(response,object.toString());
    }

    public JSONObject uploadImg(MultipartFile file, HttpServletRequest request, HttpServletResponse response){

        JSONObject object = new JSONObject();
        try{
            //判断 文件类型
            String typeName = "imgFileName";
            //0.获得项目真实路径
            String rootPath = this.getClass().getResource("/").getPath();
            String osName = System.getProperties().getProperty("os.name");
            //判断当前系统
            // URLDecoder.decode(rootPath, "UTF-8") 防止中文乱码
            String sBasePath= URLDecoder.decode(rootPath, "UTF-8")+"\\static\\file\\upload\\"+typeName+"\\";//获得存储根路径
            if (osName.toLowerCase().indexOf("windows")==-1) {
                sBasePath= "/img/file/upload/"+typeName+"/";//获得存储根路径
            }
            log.info("sBasePath----------->:"+sBasePath);
            System.out.printf("sBasePath----------->:"+sBasePath);
            if(true){
                //0.輸出圖片
                JSONObject sNetPath=inputImg(request, response, file,sBasePath,1);
                JSONObject data = new JSONObject();
                data.put("urlLoad","/file/upload/"+typeName+"/"+sNetPath.getString("url"));
                data.put("path","/file/upload/"+typeName+"");
                data.put("name",""+sNetPath.getString("url"));
                //2.返回消息
                object.put("data", data);
                object.put("msg", "上传成功");
                object.put("code", 0);
            }else{
                object.put("msg", "上传文件格式不对");
                object.put("code", -1);
            }
        }catch(Exception e){
            e.printStackTrace();
            object.put("msg", "上传失败");
        }
        return object;
    }
    @RequestMapping(params="imgloads")
    public void filesUpload(@RequestParam(value="file",required=false) MultipartFile[] files,
                            HttpServletRequest request, HttpServletResponse response) throws IOException {
        JSONObject object = new JSONObject();
        JSONArray array = new JSONArray();
        //判断 文件类型
        String typeName = "imgFileName";
        //0.获得项目真实路径
        String sRootPath=request.getSession().getServletContext().getRealPath("");
        String sBasePath=sRootPath+"\\upload\\"+typeName+"\\";//获得存储根路径
        if (files != null && files.length > 0) {
            for (int i = 0; i < files.length; i++) {
                MultipartFile file = files[i];
                // 保存文件
                //0.輸出圖片
                JSONObject sNetPath=inputImg(request, response, file,sBasePath,1);
                JSONObject data = new JSONObject();
                data.put("urlLoad","/upload/"+typeName+"/"+sNetPath.getString("url"));
                data.put("path","/upload/"+typeName+"");
                data.put("name",""+sNetPath.getString("url"));
                array.add(data);

            }
        }
        //2.返回消息
        object.put("data", array);
        object.put("msg", "上传成功");
        object.put("code", 1);
        MachineUtil.print(response,object.toString());
    }

/*****************************************************************辅助方法*****************************************************************************************/

    /**
     * 文本編輯器上傳圖片
     * @param file
     * @param request
     * @param response
     */
    private JSONObject inputImg(HttpServletRequest request, HttpServletResponse response, MultipartFile file, String sBasePath, int type) throws IOException{
        JSONObject result=new JSONObject();
        String sNowMonth= DateUtils.getNowDate("yyyyMM");
        File OutfileFolder=new File(sBasePath+"/"+sNowMonth);
        if (!OutfileFolder.exists() && !OutfileFolder.isDirectory()){
            OutfileFolder.mkdirs();
        }
        //2.设置存储地址
        String sContentType=(file.getOriginalFilename()).split("\\.")[1];
        String sNowDate=DateUtils.getNowDate("yyyyMMddHHmmSSss");
        String sSavePath=sBasePath+"/"+sNowMonth+"/"+sNowDate+"."+sContentType;//保存物理路径
//		String sNetPath="/upload/img/"+sNowMonth+"/"+sNowDate+"."+sContentType;//访问地址
        //3.输出文件
        InputStream input=file.getInputStream();

        commonFileOutPut(input, sContentType, sSavePath);//输出原图文件
        input.close();
        System.out.printf("进入上传图片方法---------->生成图片");

        if(FILE_TYPE_IMG == type){
            System.out.printf("进入上传图片方法---------->生成图片_360");
            InputStream oriInput=new BufferedInputStream(new FileInputStream(sSavePath));
            imgCut(oriInput, sContentType, sBasePath+"/"+sNowMonth+"/"+sNowDate+"."+sContentType+"_360",0,0);//输出压缩大小文件
        }
        //4.組織json
        result.put("name", sNowDate+"."+sContentType);
        result.put("originalName", file.getOriginalFilename());
        result.put("size", "");
        result.put("state", "SUCCESS");
        result.put("type", "."+(file.getOriginalFilename()).split("\\.")[1]);
        result.put("url", sNowMonth+"/"+sNowDate+"."+sContentType);
        return result;
    }

    /**
     * 输出截取图片
     * @param input
     * @param sContentType
     * @param outputPath
     */
    private void imgCut(InputStream input,String sContentType,String outputPath,int height,int width){
        try{
            FileOutputStream out = new FileOutputStream(outputPath);

            // 0.取得图片读入器
            Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(sContentType);
            ImageReader reader = readers.next();
            ImageInputStream iis = ImageIO.createImageInputStream(input);
            reader.setInput(iis, true);

            ImageReadParam param=null;
            // 2.计算截取长宽
            if(height==0 || width==0)
            {
                width=360;
                Double scale=360D / Double.valueOf(reader.getWidth(0));
                Double nowHeight= MathDelUtil.halfUp(scale * reader.getHeight(0), 0);
                height=nowHeight.intValue();
            }else{
                // 3.设定截取范围
                param = reader.getDefaultReadParam();
                Rectangle rect = new Rectangle(0, 0, width, height);
                param.setSourceRegion(rect);
            }

            BufferedImage bi;
            if(param!=null) {
                bi = reader.read(0, param);
            } else {
                bi=reader.read(0);
            }

            // 4.输出截取图片
            Image image=bi.getScaledInstance(width, height, Image.SCALE_DEFAULT);
            BufferedImage show_img =new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = show_img.createGraphics();
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING , RenderingHints.VALUE_ANTIALIAS_ON);//抗锯齿
            g.drawImage(image, 0, 0, null); // 绘制图像
            g.dispose();

            ImageIO.write(show_img, sContentType, out);
            out.flush();
            out.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 通常文件输出
     * @param input
     * @param sContentType
     * @param outputPath
     */
    private void commonFileOutPut(InputStream input,String sContentType,String outputPath){
        try{
            FileOutputStream fos=new FileOutputStream(new File(outputPath));
            byte[] buffer = new byte[1024];
            int len;
            while ((len = input.read(buffer)) > 0) {
                fos.write(buffer, 0, len);
            }
            fos.flush();
            fos.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
